home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / libdi.d / os_demo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  6.5 KB  |  301 lines

  1. /*
  2.  *   libdi - CD Audio Player Device Interface Library
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  */
  22. #ifndef LINT
  23. static char *_os_demo_c_ident_ = "@(#)os_demo.c    5.7 94/12/28";
  24. #endif
  25.  
  26. #include "common.d/appenv.h"
  27. #include "common.d/util.h"
  28. #include "libdi.d/libdi.h"
  29. #include "libdi.d/scsipt.h"
  30.  
  31. #ifdef DEMO_ONLY
  32.  
  33. extern appdata_t    app_data;
  34. extern bool_t        scsipt_notrom_error;
  35. extern FILE        *errfp;
  36.  
  37. int            cdsim_sfd[2] = { -1, -1 },
  38.             cdsim_rfd[2] = { -1, -1 };
  39. STATIC pid_t        cdsim_pid = -1;
  40.  
  41.  
  42. /*
  43.  * pthru_send
  44.  *    Build SCSI CDB and send command to the device.
  45.  *
  46.  * Args:
  47.  *    opcode - SCSI command opcode
  48.  *    addr - The "address" portion of the SCSI CDB
  49.  *    buf - Pointer to data buffer
  50.  *    size - Number of bytes to transfer
  51.  *    rsvd - The "reserved" portion of the SCSI CDB
  52.  *    length - The "length" portion of the SCSI CDB
  53.  *    param - The "param" portion of the SCSI CDB
  54.  *    control - The "control" portion of the SCSI CDB
  55.  *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  56.  *    prnerr - Whether an error message should be displayed
  57.  *         when a command fails
  58.  *
  59.  * Return:
  60.  *    TRUE - command completed successfully
  61.  *    FALSE - command failed
  62.  */
  63. bool_t
  64. pthru_send(
  65.     byte_t        opcode,
  66.     word32_t    addr,
  67.     byte_t        *buf,
  68.     word32_t    size,
  69.     byte_t        rsvd,
  70.     word32_t    length,
  71.     byte_t        param,
  72.     byte_t        control,
  73.     byte_t        rw,
  74.     bool_t        prnerr
  75. )
  76. {
  77.     simpkt_t    spkt,
  78.             rpkt;
  79.     static word32_t    pktid = 0;
  80.  
  81.     if (cdsim_rfd[0] < 0 || cdsim_sfd[1] < 0 || scsipt_notrom_error)
  82.         return FALSE;
  83.  
  84.     memset(&spkt, 0, CDSIM_PKTSZ);
  85.     memset(&rpkt, 0, CDSIM_PKTSZ);
  86.  
  87.     /* Set up SCSI CDB */
  88.     switch (opcode & 0xf0) {
  89.     case 0xa0:
  90.     case 0xe0:
  91.         /* 12-byte commands */
  92.         spkt.cdbsz = 12;
  93.         spkt.cdb[0] = opcode;
  94.         spkt.cdb[1] = param;
  95.         spkt.cdb[2] = (addr >> 24) & 0xff;
  96.         spkt.cdb[3] = (addr >> 16) & 0xff;
  97.         spkt.cdb[4] = (addr >> 8) & 0xff;
  98.         spkt.cdb[5] = (addr & 0xff);
  99.         spkt.cdb[6] = (length >> 24) & 0xff;
  100.         spkt.cdb[7] = (length >> 16) & 0xff;
  101.         spkt.cdb[8] = (length >> 8) & 0xff;
  102.         spkt.cdb[9] = length & 0xff;
  103.         spkt.cdb[10] = rsvd;
  104.         spkt.cdb[11] = control;
  105.         break;
  106.  
  107.     case 0xc0:
  108.     case 0xd0:
  109.     case 0x20:
  110.     case 0x30:
  111.     case 0x40:
  112.         /* 10-byte commands */
  113.         spkt.cdbsz = 10;
  114.         spkt.cdb[0] = opcode;
  115.         spkt.cdb[1] = param;
  116.         spkt.cdb[2] = (addr >> 24) & 0xff;
  117.         spkt.cdb[3] = (addr >> 16) & 0xff;
  118.         spkt.cdb[4] = (addr >> 8) & 0xff;
  119.         spkt.cdb[5] = addr & 0xff;
  120.         spkt.cdb[6] = rsvd;
  121.         spkt.cdb[7] = (length >> 8) & 0xff;
  122.         spkt.cdb[8] = length & 0xff;
  123.         spkt.cdb[9] = control;
  124.         break;
  125.  
  126.     case 0x00:
  127.     case 0x10:
  128.         /* 6-byte commands */
  129.         spkt.cdbsz = 6;
  130.         spkt.cdb[0] = opcode;
  131.         spkt.cdb[1] = param;
  132.         spkt.cdb[2] = (addr >> 8) & 0xff;
  133.         spkt.cdb[3] = addr & 0xff;
  134.         spkt.cdb[4] = length & 0xff;
  135.         spkt.cdb[5] = control;
  136.         break;
  137.  
  138.     default:
  139.         if (app_data.scsierr_msg && prnerr)
  140.             fprintf(errfp, "0x%02x: Unknown SCSI opcode\n",
  141.                 opcode);
  142.         return FALSE;
  143.     }
  144.  
  145.     spkt.len = (size > MAX_DATALEN) ? MAX_DATALEN : size;
  146.     spkt.dir = rw;
  147.     spkt.pktid = ++pktid;
  148.  
  149.     /* Reset packet id if overflowing */
  150.     if (pktid == 0xffff)
  151.         pktid = 0;
  152.  
  153.     /* Copy data from user buffer into packet */
  154.     if (rw == WRITE_OP && buf != NULL && spkt.len != 0)
  155.         memcpy(spkt.data, buf, spkt.len);
  156.  
  157.     /* Send command packet */
  158.     if (!cdsim_sendpkt("pthru", cdsim_sfd[1], &spkt))
  159.         return FALSE;
  160.  
  161.     /* Get response packet */
  162.     if (!cdsim_getpkt("pthru", cdsim_rfd[0], &rpkt))
  163.         return FALSE;
  164.  
  165.     /* Sanity check */
  166.     if (rpkt.pktid != spkt.pktid) {
  167.         if (app_data.scsierr_msg && prnerr)
  168.             fprintf(errfp, "pthru: packet sequence error.\n");
  169.  
  170.         return FALSE;
  171.     }
  172.  
  173.     /* Check return status */
  174.     if (rpkt.retcode != CDSIM_COMPOK) {
  175.         if (app_data.scsierr_msg && prnerr)
  176.             fprintf(errfp,
  177.                 "pthru: cmd error (opcode=0x%x status=%d).\n",
  178.                 rpkt.cdb[0], rpkt.retcode);
  179.  
  180.         return FALSE;
  181.     }
  182.  
  183.     /* Copy data from packet into user buffer */
  184.     if (rw == READ_OP && buf != NULL && rpkt.len != 0)
  185.         memcpy(buf, rpkt.data, rpkt.len);
  186.  
  187.     return TRUE;
  188. }
  189.  
  190.  
  191. /*
  192.  * pthru_open
  193.  *    Open SCSI pass-through device
  194.  *
  195.  * Args:
  196.  *    path - device path name string
  197.  *
  198.  * Return:
  199.  *    TRUE - open successful
  200.  *    FALSE - open failed
  201.  */
  202. /*ARGSUSED*/
  203. bool_t
  204. pthru_open(char *path)
  205. {
  206.     /* Hard code some capabilities parameters for the
  207.      * simulated CD-ROM drive.  This overrides the
  208.      * parameters from the device-specific config files.
  209.      */
  210.     app_data.device = "(none)";
  211.     app_data.vendor_code = VENDOR_SCSI2;
  212.     app_data.play10_supp = TRUE;
  213.     app_data.play12_supp = TRUE;
  214.     app_data.playmsf_supp = TRUE;
  215.     app_data.playti_supp = TRUE;
  216.     app_data.load_supp = TRUE;
  217.     app_data.eject_supp = TRUE;
  218.     app_data.msen_dbd = FALSE;
  219.     app_data.mselvol_supp = TRUE;
  220.     app_data.balance_supp = TRUE;
  221.     app_data.chroute_supp = TRUE;
  222.     app_data.pause_supp = TRUE;
  223.     app_data.caddylock_supp = TRUE;
  224.     app_data.curpos_fmt = TRUE;
  225.  
  226.     /* Open pipe for IPC */
  227.     if (pipe(cdsim_sfd) < 0 || pipe(cdsim_rfd) < 0) {
  228.         cd_fatal_popup(app_data.str_fatal, "Cannot open pipe.");
  229.         return FALSE;
  230.     }
  231.  
  232.     /* Fork the CD simulator child */
  233.     switch (cdsim_pid = fork()) {
  234.     case -1:
  235.         cd_fatal_popup(app_data.str_fatal, "Cannot fork.");
  236.         return FALSE;
  237.  
  238.     case 0:
  239.         /* Child: run CD simulator */
  240.         cdsim_main();
  241.         exit(0);
  242.  
  243.     default:
  244.         /* Parent: continue running the CD player */
  245.         DBGPRN(errfp, "pthru: forked cdsim child pid=%d\n", cdsim_pid);
  246.         break;
  247.     }
  248.  
  249.     return TRUE;
  250. }
  251.  
  252.  
  253. /*
  254.  * pthru_close
  255.  *    Close SCSI pass-through device
  256.  *
  257.  * Args:
  258.  *    Nothing.
  259.  *
  260.  * Return:
  261.  *    Nothing.
  262.  */
  263. void
  264. pthru_close(void)
  265. {
  266.     waitret_t    stat_val;
  267.  
  268.     /* Close down pipes */
  269.     close(cdsim_sfd[0]);
  270.     close(cdsim_sfd[1]);
  271.     close(cdsim_rfd[0]);
  272.     close(cdsim_rfd[1]);
  273.  
  274.     /* Shut down child */
  275.     if (cdsim_pid > 0 && kill(cdsim_pid, 0) == 0)
  276.         kill(cdsim_pid, SIGTERM);
  277.  
  278.     /* Wait for child to exit */
  279.     waitpid(cdsim_pid, &stat_val, 0);
  280. }
  281.  
  282.  
  283. /*
  284.  * pthru_vers
  285.  *    Return OS Interface Module version string
  286.  *
  287.  * Args:
  288.  *    Nothing.
  289.  *
  290.  * Return:
  291.  *    Module version text string.
  292.  */
  293. char *
  294. pthru_vers(void)
  295. {
  296.     return ("OS Interface module (Demo Dummy)\n");
  297. }
  298.  
  299. #endif    /* DEMO_ONLY */
  300.  
  301.